home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 251_01 / advcom.c < prev    next >
Text File  |  1987-10-27  |  15KB  |  657 lines

  1. /* advcom.c - a compiler for adventure games */
  2. /*
  3.     Copyright (c) 1986, by David Michael Betz
  4.     All rights reserved
  5. */
  6.  
  7. #include "advcom.h"
  8. #include "advavl.h"
  9. #include "advdbs.h"
  10.  
  11. /* symbol tables */
  12. SYMBOL *symbols;
  13. ARGUMENT *arguments;
  14. ARGUMENT *temporaries;
  15.  
  16. /* adventure id information */
  17. char aname[19];
  18. int aversion;
  19.  
  20. /* word table */
  21. int wtable[WMAX+1],wcnt;
  22.  
  23. /* object table */
  24. int otable[OMAX+1],ocnt;
  25.  
  26. /* action table */
  27. int atable[AMAX+1],acnt;
  28.  
  29. /* constant, variable and property symbol counts */
  30. int ccnt,vcnt,pcnt;
  31.  
  32. /* data and code space */
  33. char *data,*code;
  34. int dptr,cptr;
  35.  
  36. /* buffer for building an object */
  37. int objbuf[OSIZE];
  38. int nprops;
  39.  
  40. /* global variables */
  41. char ifile[FMAX];    /* input file name */
  42. char ofile[FMAX];    /* output file name */
  43. FILE *ifp;        /* input file pointer */
  44. unsigned int msgoff;    /* message section offset */
  45. TREE *words;        /* word tree */
  46. int curwrd;        /* current word number */
  47. int curobj;        /* current object */
  48. int curact;        /* current action */
  49. int def_flag;        /* default action flag value */
  50. int def_mask;        /* default action mask value */
  51.  
  52. /* header information variables */
  53. int h_init;        /* initialization code */
  54. int h_update;        /* update code */
  55. int h_before;        /* before handler code */
  56. int h_after;        /* after handler code */
  57. int h_error;        /* error handling code */
  58.  
  59. /* external routines */
  60. extern char *malloc();
  61. extern char *calloc();
  62. extern TREE *tnew();
  63.  
  64. /* external variables */
  65. extern int errcount;    /* error count */
  66. extern int t_value;    /* token value */
  67. extern char t_token[];    /* token string */
  68. extern char *t_names[];    /* token names */
  69. extern long ad_foff;    /* data file offset */
  70.  
  71. /* forward declarations */
  72. SYMBOL *sfind();
  73. SYMBOL *senter();
  74. char *save();
  75.  
  76. /* main - the main routine */
  77. main(argc,argv)
  78.   int argc; char *argv[];
  79. {
  80.     int tkn,obj,i;
  81.  
  82.     /* initialize */
  83. #ifdef MAC
  84.     macinit(ifile,ofile);
  85. #else
  86.     printf("ADVCOM v1.2 - Copyright (c) 1986, by David Betz\n");
  87. #endif
  88.     wcnt = ocnt = acnt = ccnt = vcnt = pcnt = msgoff = 0;
  89.     symbols = NULL; arguments = temporaries = NULL;
  90.     h_init = h_update = h_before = h_after = h_error = NIL;
  91.     def_flag = def_mask = 0;
  92.     aname[0] = 0;
  93.     sinit();
  94.  
  95.     /* setup the code and data space */
  96.     if ((data = calloc(1,DMAX)) == 0)
  97.     fail("insufficient memory");
  98.     if ((code = calloc(1,CMAX)) == 0)
  99.     fail("insufficient memory");
  100.     dptr = cptr = 1;    /* make sure nothing has a zero offset */
  101.  
  102.     /* get the file name */
  103. #ifndef MAC
  104.     if (argc < 2)
  105.     fail("usage: advcom <file> [ <ofile> ]");
  106.     strcpy(ifile,argv[1]); strcat(ifile,".adv");
  107.     strcpy(ofile,(argc < 3 ? argv[1] : argv[2])); strcat(ofile,".dat");
  108. #endif
  109.  
  110.     /* open the input file */
  111.     if ((ifp = fopen(ifile,"r")) == NULL)
  112.     fail("can't open input file");
  113.  
  114.     /* create and initialize the output file */
  115.     ad_create(ofile);
  116.     for (i = 0; i++ < 512; ad_putc('\0'))
  117.     ;
  118.  
  119.     /* create the word tree */
  120.     words = tnew();
  121.  
  122.     /* enter builtin constants */
  123.     center("t",-1);
  124.     center("nil",0);
  125.  
  126.     /* enter the builtin variables */
  127.     venter("$actor");
  128.     venter("$action");
  129.     venter("$dobject");
  130.     venter("$ndobjects");
  131.     venter("$iobject");
  132.     venter("$ocount");
  133.  
  134.     /* enter the preposition "to" */
  135.     add_word("to",WT_PREPOSITION);
  136.  
  137.     /* process statements until end of file */
  138.     while ((tkn = token()) == T_OPEN) {
  139.     frequire(T_IDENTIFIER);
  140.  
  141.     /* identification statement */
  142.     if (match("adventure"))
  143.         do_adventure();
  144.  
  145.     /* vocabulary statements */
  146.     else if (match("adjective"))
  147.         do_word(WT_ADJECTIVE);
  148.     else if (match("preposition"))
  149.         do_word(WT_PREPOSITION);
  150.     else if (match("conjunction"))
  151.         do_word(WT_CONJUNCTION);
  152.     else if (match("article"))
  153.         do_word(WT_ARTICLE);
  154.     else if (match("synonym"))
  155.         do_synonym();
  156.  
  157.     /* constant, variable, function and default definition statements */
  158.     else if (match("define"))
  159.         do_define();
  160.     else if (match("variable"))
  161.         do_variable();
  162.     else if (match("default"))
  163.         do_default();
  164.  
  165.     /* property definition statement */
  166.     else if (match("property"))
  167.         do_defproperty();
  168.  
  169.     /* handle the init, before and after code statements */
  170.     else if (match("init"))
  171.         h_init = do_code(t_token);
  172.     else if (match("update"))
  173.         h_update = do_code(t_token);
  174.     else if (match("before"))
  175.         h_before = do_code(t_token);
  176.     else if (match("after"))
  177.         h_after = do_code(t_token);
  178.     else if (match("error"))
  179.         h_error = do_code(t_token);
  180.  
  181.     /* action definition statement */
  182.     else if (match("action"))
  183.         do_action();
  184.  
  185.     /* object definition statements */
  186.         else if (match("object"))
  187.         do_object(t_token,NIL);
  188.  
  189.     /* object instance definition statements */
  190.     else if (obj = ofind(t_token))
  191.         do_object(t_token,obj);
  192.  
  193.     /* error, unknown statement */
  194.     else
  195.         error("Unknown statement type");
  196.     }
  197.     require(tkn,T_EOF);
  198.  
  199.     /* close the input file */
  200.     fclose(ifp);
  201.  
  202.     /* output the data structures */
  203.     output();
  204.  
  205.     /* close the output file */
  206.     ad_close();
  207. }
  208.  
  209. /* getvalue - get a value */
  210. int getvalue()
  211. {
  212.     SYMBOL *sym;
  213.  
  214.     switch (token()) {
  215.     case T_IDENTIFIER:    if (sym = sfind(t_token))
  216.                 return (sym->s_value);
  217.             return (oenter(t_token));
  218.     case T_NUMBER:    return (t_value);
  219.     case T_STRING:    return (t_value);
  220.     default:        error("Expecting identifier, number or string");
  221.             return (0);
  222.     }
  223. }
  224.  
  225. /* dalloc - allocate data space */
  226. int dalloc(size)
  227.   int size;
  228. {
  229.     if ((dptr += size) > DMAX)
  230.     fail("out of data space");
  231.     return (dptr - size);
  232. }
  233.  
  234. /* add_word - add a word to the dictionary */
  235. int add_word(str,type)
  236.   char *str; int type;
  237. {
  238.     if ((curwrd = tfind(words,str)) == NIL) {
  239.     if (wcnt < WMAX) {
  240.         curwrd = ++wcnt;
  241.         wtable[curwrd] = type;
  242.         tenter(words,str);
  243.     }
  244.     else {
  245.         error("too many words");
  246.         curwrd = 0;
  247.     }
  248.     }
  249.     else if (wtable[curwrd] == WT_UNKNOWN)
  250.     wtable[curwrd] = type;
  251.     else if (type != WT_UNKNOWN && type != wtable[curwrd])
  252.     error("Ambiguous word type");
  253.     return (curwrd);
  254. }
  255.  
  256. /* add_synonym - add a synonym to a word */
  257. int add_synonym(str,wrd)
  258.   char *str; int wrd;
  259. {
  260.     curwrd = wrd;
  261.     return (tenter(words,str));
  262. }
  263.  
  264. /* getword - get a word from an object field */
  265. int getword(off)
  266.   int off;
  267. {
  268.     return ((data[off] & 0xFF) | (data[off+1] << 8));
  269. }
  270.  
  271. /* putword - put a word into an object field */
  272. putword(off,dat)
  273.   int off,dat;
  274. {
  275.     data[off] = dat;
  276.     data[off+1] = dat >> 8;
  277. }
  278.  
  279. /* getbyte - get a byte from an object field */
  280. int getbyte(off)
  281.   int off;
  282. {
  283.     return (data[off]);
  284. }
  285.  
  286. /* putbyte - put a byte into an object field */
  287. putbyte(off,dat)
  288.   int off,dat;
  289. {
  290.     data[off] = dat;
  291. }
  292.  
  293. /* output - output the binary data structures */
  294. output()
  295. {
  296.     int woff,wsize;    /* word table offset and size */
  297.     int ooff,osize;    /* object table offset and size */
  298.     int aoff,asize;    /* action table offset and size */
  299.     int toff,tsize;    /* word type table offset and size */
  300.     int voff,vsize;    /* variable table offset and size */
  301.     int soff,ssize;    /* save area offset and size */
  302.     int dsize;        /* data size without dictionary */
  303.     int dbase,cbase,size,mblk,dblk,i;
  304.  
  305.     /* make sure the adventure id information is present */
  306.     if (aname[0] == 0) {
  307.     xerror("no adventure identification information");
  308.     strcpy(aname,"ADVENTURE");
  309.     aversion = 0;
  310.     }
  311.  
  312.     /* pad the remainder of this message block */
  313.     while (msgoff & 0x007F)
  314.     { ad_putc('\0'); ad_putc('\0'); ad_putc('\0'); ad_putc('\0'); msgoff++; }
  315.  
  316.     /* save the size of the data area before the dictionary */
  317.     dsize = dptr;
  318.  
  319.     /* insert the vocabulary into the data array */
  320.     woutput(words->tr_root);
  321.  
  322.     /* compute table offsets */
  323.     woff = 0;            wsize = tentries(words) * 2 + 2;
  324.     toff = woff + wsize; tsize = wcnt;
  325.     ooff = toff + tsize; osize = ocnt * 2 + 2;
  326.     aoff = ooff + osize; asize = acnt * 2 + 2;
  327.     voff = aoff + asize; vsize = vcnt * 2 + 2;
  328.     dbase = voff + vsize;
  329.     cbase =